package org.hepeng.fabric.gateway.contract.spring;

import org.hepeng.fabric.contract.api.annotation.ContractAPI;
import org.hepeng.fabric.gateway.contract.proxy.FabricGatewayObjectHolder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * @author he peng
 * @date 2022/3/25
 */

@Configuration
@Import(ContractAutoConfiguration.AutoConfiguredContractScannerRegistrar.class)
public class ContractAutoConfiguration implements BeanFactoryAware {

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        FabricGatewayObjectHolder.setBeanFactory(beanFactory);
    }

    @Configuration
    public static class AutoConfiguredContractScannerRegistrar implements ImportBeanDefinitionRegistrar , BeanFactoryAware {

        private BeanFactory beanFactory;

        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

            List<String> packages = AutoConfigurationPackages.get(this.beanFactory);

            ClassPathContractScanner scanner = new ClassPathContractScanner(registry);
            scanner.setAnnotationClass(ContractAPI.class);
            scanner.registerFilters();
            scanner.doScan(StringUtils.toStringArray(packages));
        }

        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            this.beanFactory = beanFactory;
        }
    }
}
